#pragma once
#ifndef Game_Common_Collection_h
#define Game_Common_Collection_h

#include <vector>
#include "ICollection.h"

namespace Game {
namespace Common {

template<typename T>
class CollectionIterator;

using namespace std;

template<typename T>
class Collection : public ICollection<T> {
public:
    friend CollectionIterator<T>;
    Collection();
    virtual ~Collection();
    virtual int GetCount();
    virtual void Add(T item);
    virtual void Clear();
    virtual T GetItem(int index);
    virtual int IndexOf(T item);
    virtual bool Remove(T item);
    virtual void RemoveAt(int index);
    _Vector_iterator<T> Iterator();
private:
    vector<T>* items;
};

template<typename T>
Collection<T>::Collection() {
    this->items = new vector<T>();
}

template<typename T>
Collection<T>::~Collection() {
    SAFE_DELETE(this->items);
}

template<typename T>
void Collection<T>::Add(T item) {
    this->items->push_back(item);
}

template<typename T>
void Collection<T>::Clear() {
    this->items->clear();
}

template<typename T>
int Collection<T>::GetCount() {
    return this->items->size();
}

template<typename T>
T Collection<T>::GetItem(int index) {
    return (*this->items)[index];
}

template<typename T>
int Collection<T>::IndexOf(T item) {
    for (unsigned int i = 0; i < this->items->size(); i++) {
        if (item == (*this->items)[i]) {
            return i;
        }
    }

    return -1;
}

template<typename T>
bool Collection<T>::Remove(T item) {
    int index = this->IndexOf(item);
    if (index < 0) {
        return false;
    }

    this->RemoveAt(index);
    return true;
}

template<typename T>
void Collection<T>::RemoveAt(int index) {
    this->items->erase(this->items->begin() + index);
}

template<typename T>
_Vector_iterator<T> Collection<T>::Iterator() {
    return this->items.begin();
}


template<typename T>
class CollectionIterator : public ICollectionIterator<T> {
public:
    CollectionIterator() : stk(NULL) {
    }

    CollectionIterator(Collection<T>* s) : stk(s) {
        this->iterator = this->stk->items->begin();
    }

    virtual void operator++() {
        this->iterator++;
    }

    virtual void operator ++(int) {
        this->iterator++;
    }

    virtual bool operator()() {
        return this->iterator != this->stk->items->end();
    }

    virtual T operator *() {
        return *this->iterator;
    }
private:
    Collection<T>* stk;
    _Vector_iterator<_Vector_val<T, allocator<T>>> iterator;
};

}
}

#endif
